import os
import json
import subprocess
import logging
import shutil
from mutagen import File
from pathlib import Path

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 定义路径
INPUT_DIR = Path('input')
TEMP_DIR = Path('temp')
OUTPUT_DIR = Path('output')  # 输出到output文件夹

# 创建输出目录
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)

# 定义无损格式扩展名
LOSSLESS_FORMATS = {'.flac', '.alac', '.ape', '.wav', '.wv', '.tta', '.tak'}

def get_bitrate(file_path):
    """获取音频文件的比特率（kbps）"""
    try:
        audio = File(file_path)
        if audio is not None:
            # 计算比特率 (比特率 = 文件大小(bit) / 时长(秒))
            bitrate = audio.info.bitrate // 1000  # 转换为kbps
            return bitrate
    except Exception as e:
        logging.error(f"Error reading bitrate for {file_path}: {str(e)}")
    return None

def get_metadata(json_path):
    """从JSON文件读取元数据"""
    try:
        with open(json_path, 'r', encoding='utf-8') as f:
            return json.load(f)
    except Exception as e:
        logging.error(f"Error reading metadata from {json_path}: {str(e)}")
        return {}

def convert_to_wma(input_path, output_path, bitrate, metadata):
    """使用FFmpeg转换文件为WMA格式"""
    try:
        cmd = [
            'ffmpeg',
            '-i', str(input_path),
            '-c:a', 'wmav2',
            '-b:a', f'{bitrate}k',
            '-y'  # 覆盖已存在文件
        ]
        
        # 添加元数据
        for key, value in metadata.items():
            if key != 'bitrate':  # 跳过比特率字段
                cmd.extend(['-metadata', f'{key}={value}'])
        
        cmd.append(str(output_path))
        
        result = subprocess.run(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        
        if result.returncode != 0:
            logging.error(f"FFmpeg conversion failed for {input_path}:\n{result.stderr}")
            return False
        return True
    except Exception as e:
        logging.error(f"Conversion error for {input_path}: {str(e)}")
        return False

def move_lossless_file(input_path, output_path):
    """移动无损文件到输出目录"""
    try:
        # 确保输出目录存在
        output_path.parent.mkdir(parents=True, exist_ok=True)
        
        # 如果目标文件已存在，则删除
        if output_path.exists():
            output_path.unlink()
            logging.warning(f"Deleted existing file: {output_path}")
        
        # 移动文件
        shutil.move(str(input_path), str(output_path))
        logging.info(f"Moved lossless file to: {output_path}")
        return True
    except Exception as e:
        logging.error(f"Error moving lossless file {input_path} to {output_path}: {str(e)}")
        return False

def process_files():
    """处理所有音频文件"""
    processed_files = 0
    skipped_files = 0
    moved_lossless = 0
    
    for input_path in INPUT_DIR.glob('*'):
        if not input_path.is_file():
            continue
        
        ext = input_path.suffix.lower()
        stem = input_path.stem
        
        # 处理无损文件 - 直接移动到output文件夹
        if ext in LOSSLESS_FORMATS:
            output_path = OUTPUT_DIR / input_path.name
            
            # 查找对应的元数据文件
            json_path = TEMP_DIR / f"{stem}.json"
            
            # 移动无损文件
            if move_lossless_file(input_path, output_path):
                moved_lossless += 1
                
                # 删除临时元数据文件（如果存在）
                if json_path.exists():
                    try:
                        json_path.unlink()
                        logging.info(f"Deleted metadata file: {json_path.name}")
                    except Exception as e:
                        logging.error(f"Error deleting {json_path}: {str(e)}")
            else:
                skipped_files += 1
            
            continue
        
        # 跳过WMA文件
        if ext == '.wma':
            logging.info(f"Skipping existing WMA file: {input_path.name}")
            skipped_files += 1
            continue
        
        # 查找对应的元数据文件
        json_path = TEMP_DIR / f"{stem}.json"
        if not json_path.exists():
            logging.warning(f"No metadata found for {input_path.name}")
            skipped_files += 1
            continue
        
        # 获取比特率和元数据
        bitrate = get_bitrate(input_path)
        if bitrate is None:
            logging.warning(f"Cannot determine bitrate for {input_path.name}")
            skipped_files += 1
            continue
        
        metadata = get_metadata(json_path)
        
        # 准备输出路径
        output_path = OUTPUT_DIR / f"{stem}.wma"
        
        # 转换文件
        logging.info(f"Converting {input_path.name} to WMA (bitrate: {bitrate}kbps)")
        if convert_to_wma(input_path, output_path, bitrate, metadata):
            # 删除临时元数据文件
            try:
                json_path.unlink()
                logging.info(f"Deleted metadata file: {json_path.name}")
            except Exception as e:
                logging.error(f"Error deleting {json_path}: {str(e)}")
            
            processed_files += 1
        else:
            skipped_files += 1
    
    logging.info(f"Processing completed: {processed_files} files converted, {moved_lossless} lossless files moved, {skipped_files} files skipped")

if __name__ == "__main__":
    # 检查依赖
    try:
        subprocess.run(['ffmpeg', '-version'], check=True, 
                      stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    except (subprocess.CalledProcessError, FileNotFoundError):
        logging.error("FFmpeg not found! Please install FFmpeg and add it to PATH")
        exit(1)
    
    # 检查输入目录
    if not INPUT_DIR.exists():
        logging.error(f"Input directory not found: {INPUT_DIR}")
        exit(1)
    
    # 检查临时目录
    if not TEMP_DIR.exists():
        logging.warning(f"Temporary directory not found: {TEMP_DIR}")
    
    # 处理文件
    process_files()